﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObjectRelationalMap.Interfaces;

namespace ObjectRelationalMap.Models
{
    public partial class ORM: IReadModels, IReadWriteModels
    {
        public event EventHandler AnecdotesChanged;
        public event EventHandler DomainsChanged;
        public event EventHandler StudentsChanged;


        private List<Anecdote> _anecdotes = new List<Anecdote>();
        private List<Domain> _domains = new List <Domain>();
        private List<Student> _students = new List<Student>();

        public IList<Anecdote> Anecdotes
        {
            get { return _anecdotes; } 
        }
        IEnumerable<Anecdote> IReadModels.Anecdotes
        {
            get { return _anecdotes; }
        }

        public IList<Domain> Domains
        {
            get { return _domains; }
        }
        IEnumerable<Domain> IReadModels.Domains
        {
            get { return _domains; }
        }

        public IList<Student> Students
        {
            get { return _students; }
        }
        IEnumerable<Student> IReadModels.Students
        {
            get { return _students; }
        }

        public ORM()
        {
        }

        public ORM(Data.Sources.IDataSource dataSource)
        {
            LoadRelationalData(dataSource);
        }

        public Data.Models.DataModels ToRelationalData()
        {

            List<Data.Models.Student> dataStudents = new List<Data.Models.Student>();
            List<Data.Models.Domain> dataDomains = new List<Data.Models.Domain>();
            List<Data.Models.Anecdote> dataAnecdotes = new List<Data.Models.Anecdote>();

            foreach (Domain keyValue in _domains)
            {
                dataDomains.Add(new Data.Models.Domain() { ID = keyValue.ID, Name = keyValue.Name });
            }

            foreach (Student keyValue in _students)
            {
                dataStudents.Add(new Data.Models.Student() { ID = keyValue.ID, Name = keyValue.Name });
            }

            foreach (Anecdote keyValue in _anecdotes)
            {
                int id = keyValue.ID;
                Anecdote anecdote = keyValue;
                int domainID = _domains.GetByName(anecdote.Domain).ID;
                int studentID = _students.GetByName(anecdote.Student).ID;
                dataAnecdotes.Add(new Data.Models.Anecdote()
                                            {
                                                ID = id,
                                                DomainID = domainID,
                                                StudentID = studentID,
                                                Note = anecdote.Note,
                                                Date = anecdote.Date
                                            });
            }



            return new Data.Models.DataModels(){
                                                    Anecdotes = dataAnecdotes,
                                                    Domains = dataDomains,
                                                    Students = dataStudents
                                               };
        }

        public void LoadRelationalData(Data.Sources.IDataSource dataSource)
        {
            Data.Models.DataModels dataModels = dataSource.GetData();

            InitializeData();

            foreach (Data.Models.Domain dataDomain in dataModels.Domains)
            {
                _domains.Add(new Domain()
                                {
                                    ID = dataDomain.ID,
                                    Name = dataDomain.Name
                                });
            }

            foreach (Data.Models.Student dataStudent in dataModels.Students)
            {
                _students.Add(new Student()
                                 {
                                     ID = dataStudent.ID,
                                     Name = dataStudent.Name
                                 });
            }

            foreach (Data.Models.Anecdote dataAnecdote in dataModels.Anecdotes)
            {
                _anecdotes.Add(new Anecdote()
                               {
                                   ID = dataAnecdote.ID,
                                   Student = _students[dataAnecdote.StudentID].Name,
                                   Domain = _domains[dataAnecdote.DomainID].Name,
                                   Note = dataAnecdote.Note,
                                   Date = dataAnecdote.Date
                               });
            }

            if (AnecdotesChanged != null)
                AnecdotesChanged.Invoke(this, new EventArgs());
            
            if (DomainsChanged != null)
                DomainsChanged.Invoke(this, new EventArgs());
            
            if(StudentsChanged != null)
                StudentsChanged.Invoke(this, new EventArgs());
        }

        private int GetNextKey(IEnumerable<int> keys)
        {
            int maxKey = -1;
            foreach (int key in keys)
            {
                if (key > maxKey)
                {
                    maxKey = key;
                }
            }

            return maxKey + 1;
        }

        private void InitializeData()
        {
            _anecdotes = new List<Anecdote>();
            _domains = new List<Domain>();
            _students = new List<Student>();
        }
    }
}
